package com.summer.socket.im;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;

public class WSServerInitialzer extends ChannelInitializer<SocketChannel> {
	@Override
	protected void initChannel(SocketChannel ch) throws Exception {
		ChannelPipeline pipeline = ch.pipeline();
		
		// ---------------------------- 以下是针对 HTTP 的支持 ----------------------------------------
		// WebSocket 基于 Http 协议，所以需要一个 Http 编解码器
		pipeline.addLast(new HttpServerCodec());
		
		// Http 中会有一些对应的数据流传输，这些数据流有大有小，如果在这个部分对一些大的数据流有些写的处理
		// ‌ChunkedWriteHandler是Netty框架中用于异步写入大型数据流的通道处理器‌，它通过分块传输机制解决内存消耗问题，支持文件传输等场景.
		//  - 配合传输的代码 channel.write(new ChunkedFile(new File("video.mkv"))); // 支持的类型包括ChunkedFile、ChunkedStream等实现ChunkedInput接口的类
		//  - 恢复传输‌：若数据源间歇生成块（如实时流），需调用resumeTransfer()方法恢复。‌‌
		pipeline.addLast(new ChunkedWriteHandler());
		
		// 我们还需要对一些 httpMassge 进行一些处理，我们会使用到如 Request 或 Response
		// HttpObjectAggregator 它是一个聚合器，对 HttpMassge 进行聚合，聚合成 FullHttpRequest 和 FullHttpResponse。
		// 几乎在 netty 中的编程都会使用到此 Handler。对于我们不想处理的 HTTP‌‌ 请求都可以交给Netty进行处理
		pipeline.addLast(new HttpObjectAggregator(1024 * 64)); // 设定一个消息的长度：1024 * 64，单位字节
		
		// ---------------------------- 以下是针对 WebSocket 的支持 ----------------------------------------
		// 处理 WebSocket 协议的处理器类，用于指定给客户端连接访问的路由：/ws
		// 这个 Handler 会帮助处理一些繁重复杂的事：
		//   - 会帮你处理握手动作：handshaking（close, ping, pong)，ping, pong = 心跳
		//   - 对于 WebSocket 来讲，都是以 frames 进行传输的，不同的数据类型对应的 frames 也不同。
		pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));	// 参数为协议的路径，就是在请求的时候我们会有一些协议号（如 ws:)以及我们的IP和端口，这个协议号可以自定义
		
		// 添加自定义的处理类，用于处理具体消息数据的业务处理。这里处理消息的泛型类型取决管道中上一个 Handler 如何处理，如 WebSocketServerProtocolHandler 会转换成 WebSocketFrame
		pipeline.addLast(new ChatHandler());
	}
}